import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;

public class Main423 {
	
	public static void main (String args[])
	{
		long A[][];
		Scanner scan = new Scanner (System.in);
		int n = scan.nextInt();
		A = new long[n][n];
		int i = 1;
		int j = 0;
		long MAX = Integer.MAX_VALUE; 
		while (scan.hasNext()){
			String temp = scan.next();
			if (temp.equalsIgnoreCase("x")){
				A[i][j] = MAX;
				A[j][i] = MAX;
			}else{
				A[i][j] = Integer.parseInt(temp);
				A[j][i] = A[i][j];
			}
			j++;
			if (j>=i) {
				i++;
				j=0;
			}
			if (i==n) break;
		}
		executar(A,n);

	}

	static void executar(long A[][], int n){

		long[] distancias = new long[n];
		boolean [] visitados = new boolean[n];
		
		for (int i = 0; i < distancias.length; i++) {
			distancias[i] = Long.MAX_VALUE;
		}

		distancias[0] = 0;
		visitados[0] = true;
		
		for(int i = 0; i < n; i++) {
			int menor = posicaoMenorNaoVisitado(distancias, visitados);
			
			dijkstra(A, n, menor, distancias);
		}
		
		long maior = Long.MIN_VALUE;
		
		for(int i = 0; i < n; i++) {
			if(distancias[i] > maior) {
				maior = distancias[i];
			}
		}
		
		System.out.println(maior);
	}

	private static int posicaoMenorNaoVisitado(long[] distancias, boolean[] visitados) {
		
		long menor = Long.MAX_VALUE;
		int indice = -1;
		
		for(int i = 0; i < distancias.length; i++) {
			if(!visitados[i] && distancias[i] < menor) {
				menor = distancias[i];
				indice = i;
			}
		}
		return indice;
	}
	
	
	private static void dijkstra(long[][] A, int n, int menor, long[] distancias) {

		for(int j = 0; j < n; j++) {
			if(distancias[j] > distancias[menor] + A[menor][j]) {
				distancias[j] = distancias[menor] + A[menor][j];
			}
		}
	}

}